package com.atguigu.gmall.order.controller;

import com.alibaba.fastjson.JSON;
import com.atguigu.gmall.cart.client.CartFeignClient;
import com.atguigu.gmall.common.result.Result;
import com.atguigu.gmall.common.util.AuthContextHolder;
import com.atguigu.gmall.model.cart.CartInfo;
import com.atguigu.gmall.model.order.OrderDetail;
import com.atguigu.gmall.model.order.OrderInfo;
import com.atguigu.gmall.model.user.UserAddress;
import com.atguigu.gmall.order.service.OrderService;
import com.atguigu.gmall.product.client.ProductFeignClient;
import com.atguigu.gmall.user.client.UserFeignClient;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.stream.Collectors;

/**
 * @author Fxz
 * @version 1.0
 * @date 2022-02-19 16:48
 */
@SuppressWarnings("all")
@Slf4j
@RequestMapping("/api/order")
@RestController
@RequiredArgsConstructor
public class OrderApiController {

	private final OrderService orderService;

	private final ProductFeignClient productFeignClient;

	private final UserFeignClient userFeignClient;

	private final CartFeignClient cartFeignClient;

	private final ThreadPoolExecutor threadPoolExecutor;

	@GetMapping("/auth/trade")
	public Result trade(HttpServletRequest request) {
		String userId = AuthContextHolder.getUserId(request);
		HashMap<Object, Object> map = new HashMap<>();

		log.info("userId:{}", userId);

		// 用户收货地址列表
		List<UserAddress> userAddressList = userFeignClient.findUserAddressListByUserId(Long.valueOf(userId));
		// 用户选中的购物清单
		List<CartInfo> cartCheckedList = cartFeignClient.getCartCheckedList(Long.valueOf(userId));
		// 声明一个订单明细集合
		ArrayList<OrderDetail> detailArrayList = new ArrayList<>();
		if (CollectionUtils.isNotEmpty(cartCheckedList)) {
			cartCheckedList.forEach(item -> {
				OrderDetail orderDetail = new OrderDetail();
				orderDetail.setSkuId(item.getSkuId());
				orderDetail.setSkuName(item.getSkuName());
				orderDetail.setImgUrl(item.getImgUrl());
				orderDetail.setSkuNum(item.getSkuNum());
				orderDetail.setOrderPrice(item.getSkuPrice());
				orderDetail.setCreateTime(new Date());
				detailArrayList.add(orderDetail);
			});
		}
		OrderInfo orderInfo = new OrderInfo();
		orderInfo.setOrderDetailList(detailArrayList);
		orderInfo.sumTotalAmount();
		String tradeNo = orderService.getTradeNo(userId);
		map.put("tradeNo", tradeNo);
		map.put("totalAmount", orderInfo.getTotalAmount());
		map.put("total", detailArrayList.size());
		map.put("userAddressList", userAddressList);
		map.put("detailArrayList", detailArrayList);
		return Result.ok(map);
	}

	/**
	 * 保存订单
	 */
	@PostMapping("/auth/submitOrder")
	public Result submitOrder(@RequestBody OrderInfo orderInfo, HttpServletRequest request) {
		String userId = AuthContextHolder.getUserId(request);
		String tradeNo = request.getParameter("tradeNo");
		Boolean result = orderService.checkTradeNo(tradeNo, userId);
		if (result) {
			orderService.deleteTradeNo(userId);
			orderInfo.setUserId(Long.valueOf(userId));
			// 多线程执行集合
			List<CompletableFuture> futureList = new ArrayList<>();
			// 存储错误信息的集合
			List<String> errorList = new ArrayList<>();
			// 验证库存
			List<OrderDetail> orderDetailList = orderInfo.getOrderDetailList();
			if (CollectionUtils.isNotEmpty(orderDetailList)) {
				for (OrderDetail orderDetail : orderDetailList) {
					CompletableFuture<Void> stockCompletableFuture = CompletableFuture.runAsync(() -> {
						Boolean flag = orderService.checkStock(orderDetail.getSkuId(), orderDetail.getSkuNum());
						log.info("检验库存是否充足,skuId:{},skuNum:{},res:{}", orderDetail.getSkuId(), orderDetail.getSkuNum(),
								flag);
						if (!flag) {
							errorList.add(orderDetail.getSkuName() + "库存不足!");
						}
					}, threadPoolExecutor);
					futureList.add(stockCompletableFuture);

					CompletableFuture<Void> priceCompletableFuture = CompletableFuture.runAsync(() -> {
						// 订单价格
						BigDecimal orderPrice = orderDetail.getOrderPrice();
						// 实时价格
						BigDecimal skuPrice = productFeignClient.getSkuPrice(orderDetail.getSkuId());
						if (orderPrice.compareTo(skuPrice) != 0) {
							cartFeignClient.loadCartCache(userId);
							errorList.add(orderDetail.getSkuName() + "价格有变动!");
						}
					});
					futureList.add(priceCompletableFuture);
				}
			}

			// 多任务组合
			CompletableFuture.allOf(futureList.toArray(new CompletableFuture[futureList.size()])).join();
			if (CollectionUtils.isNotEmpty(errorList) && errorList.size() > 0) {
				return Result.fail().message(errorList.stream().map(String::valueOf).collect(Collectors.joining(",")));
			}
			Long orderId = orderService.saveOrderInfo(orderInfo);
			return Result.ok(orderId);
		}

		return Result.fail().message("不能重复提交订单!");
	}

	@GetMapping("/inner/getOrderInfo/{orderId}")
	public OrderInfo getOrderInfo(@PathVariable("orderId") Long orderId) {
		return orderService.getOrderInfo(orderId);
	}

	@PostMapping("/orderSplit")
	public String orderSplit(HttpServletRequest request) {
		String orderId = request.getParameter("orderId");
		String wareSkuMap = request.getParameter("wareSkuMap");
		// 跟据这两个参数进行拆单
		List<OrderInfo> orderInfos = orderService.orderSplit(orderId, wareSkuMap);
		ArrayList<Map> maps = new ArrayList<>();
		// 循环遍历
		orderInfos.forEach(orderInfo -> {
			// orderInfo转为map
			Map map = orderService.initWareOrder(orderInfo);
			maps.add(map);
		});

		return JSON.toJSONString(maps);
	}

	/**
	 * 秒杀订单数据接口
	 */
	@PostMapping("/inner/seckill/submitOrder")
	public Long submitOrder(OrderInfo orderInfo) {
		Long orderId = orderService.saveOrderInfo(orderInfo);
		return orderId;
	}

}
